```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MyBatis分页插件深度解析 | 技术小馆</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background-color: #f8fafc;
            color: #1e293b;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);
        }
        .code-block {
            background-color: #1e293b;
            border-radius: 0.5rem;
            color: #e2e8f0;
        }
        .code-block pre {
            margin: 0;
            padding: 1rem;
            overflow-x: auto;
        }
        .code-block code {
            font-family: 'Courier New', Courier, monospace;
            font-size: 0.875rem;
        }
        .hover-scale {
            transition: transform 0.2s ease;
        }
        .hover-scale:hover {
            transform: translateY(-2px);
        }
        .shadow-soft {
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
        }
        .shadow-hover:hover {
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
        }
        .highlight-box {
            border-left: 4px solid #3b82f6;
            background-color: #f8fafc;
        }
        .divider {
            height: 1px;
            background: linear-gradient(90deg, transparent, rgba(0,0,0,0.1), transparent);
        }
        .drop-cap:first-letter {
            float: left;
            font-size: 3.5rem;
            line-height: 1;
            margin-right: 0.5rem;
            margin-top: 0.25rem;
            color: #3b82f6;
            font-weight: 700;
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 md:py-32 px-4 md:px-0">
        <div class="container mx-auto max-w-4xl px-4">
            <div class="flex flex-col items-center text-center">
                <span class="bg-white bg-opacity-20 rounded-full px-4 py-1 mb-4 text-sm font-medium">技术深度解析</span>
                <h1 class="text-4xl md:text-5xl font-bold mb-6">MyBatis分页插件原理剖析</h1>
                <p class="text-xl md:text-2xl font-light max-w-2xl opacity-90">
                    探索拦截器模式在数据库分页中的精妙应用，提升你的ORM框架理解深度
                </p>
                <div class="mt-8 flex space-x-4">
                    <a href="#content" class="bg-white text-blue-600 hover:bg-blue-50 px-6 py-3 rounded-full font-medium transition-all duration-200 shadow-md hover:shadow-lg">
                        <i class="fas fa-book-open mr-2"></i>开始阅读
                    </a>
                    <a href="#visualization" class="bg-white bg-opacity-20 hover:bg-opacity-30 px-6 py-3 rounded-full font-medium transition-all duration-200 shadow-md hover:shadow-lg">
                        <i class="fas fa-project-diagram mr-2"></i>可视化解析
                    </a>
                </div>
            </div>
        </div>
    </section>

    <!-- Content Section -->
    <section id="content" class="py-16 px-4">
        <div class="container mx-auto max-w-4xl">
            <!-- Introduction -->
            <div class="mb-16">
                <p class="drop-cap text-lg text-slate-700 leading-relaxed">
                    MyBatis分页插件是用于优化SQL查询性能的一个重要工具，它能够在查询时自动根据传入的分页参数进行SQL的分页操作，从而提高数据库查询效率。本文将深入解析分页插件的设计理念、工作原理以及实现细节，帮助你全面理解这一关键技术。
                </p>
            </div>

            <!-- Section 1 -->
            <div class="mb-16 hover-scale">
                <div class="flex items-center mb-6">
                    <div class="bg-blue-100 rounded-full w-12 h-12 flex items-center justify-center mr-4">
                        <span class="text-blue-600 text-xl font-bold">1</span>
                    </div>
                    <h2 class="text-2xl md:text-3xl font-bold text-slate-800">分页插件的设计理念</h2>
                </div>
                <div class="pl-16">
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        分页插件的设计理念是通过拦截SQL执行过程，在执行查询之前修改SQL语句，加入<code class="bg-blue-50 text-blue-600 px-1 rounded">LIMIT</code>、<code class="bg-blue-50 text-blue-600 px-1 rounded">OFFSET</code>等分页参数，从而实现对SQL的分页处理。分页插件是一个典型的应用了代理模式和拦截器模式的插件，其核心是通过拦截MyBatis的<code class="bg-blue-50 text-blue-600 px-1 rounded">Executor</code>、<code class="bg-blue-50 text-blue-600 px-1 rounded">StatementHandler</code>等对象的执行方法，对查询语句进行动态修改。
                    </p>
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        分页插件的核心功能是在SQL执行前注入分页参数，并根据不同数据库的方言生成不同的分页语句。为了适应多种数据库的不同分页实现，分页插件通常会使用数据库方言来根据实际情况生成分页SQL。
                    </p>
                    
                    <div class="highlight-box p-4 rounded-lg my-6">
                        <div class="flex items-start">
                            <div class="mr-3 text-blue-500">
                                <i class="fas fa-lightbulb text-xl"></i>
                            </div>
                            <div>
                                <h4 class="font-bold text-slate-800 mb-2">设计模式应用</h4>
                                <p class="text-slate-700">
                                    分页插件巧妙结合了<strong>拦截器模式</strong>和<strong>代理模式</strong>，通过动态代理MyBatis的核心组件，在不修改原始代码的情况下实现功能扩展。
                                </p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Section 2 -->
            <div class="mb-16 hover-scale">
                <div class="flex items-center mb-6">
                    <div class="bg-blue-100 rounded-full w-12 h-12 flex items-center justify-center mr-4">
                        <span class="text-blue-600 text-xl font-bold">2</span>
                    </div>
                    <h2 class="text-2xl md:text-3xl font-bold text-slate-800">分页插件的工作原理</h2>
                </div>
                <div class="pl-16">
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        分页插件的工作原理是通过<code class="bg-blue-50 text-blue-600 px-1 rounded">Interceptor</code>接口拦截<code class="bg-blue-50 text-blue-600 px-1 rounded">StatementHandler</code>对象的<code class="bg-blue-50 text-blue-600 px-1 rounded">prepare()</code>方法，对查询SQL进行修改。在MyBatis中，<code class="bg-blue-50 text-blue-600 px-1 rounded">StatementHandler</code>是执行SQL准备工作的核心组件，其<code class="bg-blue-50 text-blue-600 px-1 rounded">prepare()</code>方法负责将SQL语句与预编译语句绑定。
                    </p>
                    <p class="text-slate-700 mb-6 leading-relaxed">
                        分页插件在<code class="bg-blue-50 text-blue-600 px-1 rounded">prepare()</code>方法执行前，对SQL语句进行修改，加入数据库特定的分页语法（例如<code class="bg-blue-50 text-blue-600 px-1 rounded">LIMIT</code>、<code class="bg-blue-50 text-blue-600 px-1 rounded">OFFSET</code>、<code class="bg-blue-50 text-blue-600 px-1 rounded">ROWNUM</code>等）。具体来说，分页插件的主要任务是：
                    </p>
                    
                    <ul class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
                        <li class="flex items-start">
                            <div class="bg-blue-100 rounded-full w-6 h-6 flex-shrink-0 flex items-center justify-center mr-3 mt-1">
                                <i class="fas fa-check text-blue-600 text-xs"></i>
                            </div>
                            <span class="text-slate-700">拦截SQL的生成过程</span>
                        </li>
                        <li class="flex items-start">
                            <div class="bg-blue-100 rounded-full w-6 h-6 flex-shrink-0 flex items-center justify-center mr-3 mt-1">
                                <i class="fas fa-check text-blue-600 text-xs"></i>
                            </div>
                            <span class="text-slate-700">解析原始SQL语句，判断是否需要分页</span>
                        </li>
                        <li class="flex items-start">
                            <div class="bg-blue-100 rounded-full w-6 h-6 flex-shrink-0 flex items-center justify-center mr-3 mt-1">
                                <i class="fas fa-check text-blue-600 text-xs"></i>
                            </div>
                            <span class="text-slate-700">修改SQL语句，加入分页参数</span>
                        </li>
                        <li class="flex items-start">
                            <div class="bg-blue-100 rounded-full w-6 h-6 flex-shrink-0 flex items-center justify-center mr-3 mt-1">
                                <i class="fas fa-check text-blue-600 text-xs"></i>
                            </div>
                            <span class="text-slate-700">执行修改后的SQL查询</span>
                        </li>
                    </ul>
                    
                    <div class="code-block shadow-soft mb-6">
                        <pre><code class="language-java">public class PageHelper implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 1. 获取 StatementHandler 对象
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        BoundSql boundSql = statementHandler.getBoundSql();
        
        // 2. 获取分页参数
        PageBounds pageBounds = getPageBoundsFromContext();

        // 3. 修改 SQL
        String originalSql = boundSql.getSql();
        String pageSql = buildPageSql(originalSql, pageBounds);

        // 4. 设置新的分页 SQL 到 BoundSql 中
        setPageSqlToBoundSql(boundSql, pageSql);

        return invocation.proceed();  // 执行修改后的 SQL
    }

    private String buildPageSql(String originalSql, PageBounds pageBounds) {
        // 生成分页 SQL 语句
        String pageSql = originalSql + " LIMIT " + pageBounds.getOffset() + ", " + pageBounds.getLimit();
        return pageSql;
    }

    private void setPageSqlToBoundSql(BoundSql boundSql, String pageSql) {
        // 修改 BoundSql 中的 SQL
        Field sqlField = BoundSql.class.getDeclaredField("sql");
        sqlField.setAccessible(true);
        sqlField.set(boundSql, pageSql);  // 替换原 SQL 为分页后的 SQL
    }

    @Override
    public Object plugin(Object target) {
        if (target instanceof StatementHandler) {
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                                          target.getClass().getInterfaces(),
                                          new StatementHandlerProxy(target));  // 为 StatementHandler 创建代理
        }
        return target;
    }

    @Override
    public void setProperties(Properties properties) {
        // 设置分页插件的属性（如数据库方言等）
    }
}</code></pre>
                    </div>
                    
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
                        <div class="bg-white p-5 rounded-lg shadow-soft hover:shadow-hover transition-shadow duration-200">
                            <div class="flex items-center mb-3">
                                <div class="bg-blue-100 text-blue-600 rounded-full w-8 h-8 flex items-center justify-center mr-3">
                                    <i class="fas fa-code"></i>
                                </div>
                                <h4 class="font-bold text-slate-800">intercept()方法</h4>
                            </div>
                            <p class="text-slate-700 text-sm">
                                该方法负责拦截StatementHandler的执行，获取原始的SQL语句，修改SQL以加入分页语法，并将修改后的SQL设置回BoundSql对象中。
                            </p>
                        </div>
                        <div class="bg-white p-5 rounded-lg shadow-soft hover:shadow-hover transition-shadow duration-200">
                            <div class="flex items-center mb-3">
                                <div class="bg-blue-100 text-blue-600 rounded-full w-8 h-8 flex items-center justify-center mr-3">
                                    <i class="fas fa-cogs"></i>
                                </div>
                                <h4 class="font-bold text-slate-800">plugin()方法</h4>
                            </div>
                            <p class="text-slate-700 text-sm">
                                将StatementHandler对象包装成代理对象，确保分页逻辑被正确应用。
                            </p>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Section 3 -->
            <div class="mb-16 hover-scale">
                <div class="flex items-center mb-6">
                    <div class="bg-blue-100 rounded-full w-12 h-12 flex items-center justify-center mr-4">
                        <span class="text-blue-600 text-xl font-bold">3</span>
                    </div>
                    <h2 class="text-2xl md:text-3xl font-bold text-slate-800">获取分页参数</h2>
                </div>
                <div class="pl-16">
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        分页插件的核心是根据当前的分页参数来生成分页SQL。在MyBatis的执行过程中，分页参数通常是通过<code class="bg-blue-50 text-blue-600 px-1 rounded">PageBounds</code>或类似的对象传递到插件中的。
                    </p>
                    <p class="text-slate-700 mb-6 leading-relaxed">
                        分页插件首先需要从执行上下文中获取分页信息。通常，分页参数会通过<code class="bg-blue-50 text-blue-600 px-1 rounded">RowBounds</code>类或自定义的<code class="bg-blue-50 text-blue-600 px-1 rounded">PageBounds</code>类传递到MyBatis框架。在分页插件中，我们需要将这些分页参数提取出来，然后根据不同的数据库方言生成相应的分页语句。
                    </p>
                    
                    <div class="code-block shadow-soft mb-6">
                        <pre><code class="language-java">private PageBounds getPageBoundsFromContext() {
    // 从上下文中获取分页信息（例如，使用ThreadLocal来存储分页信息）
    PageBounds pageBounds = PageBounds.getPageBoundsFromContext();
    return pageBounds;
}</code></pre>
                    </div>
                </div>
            </div>

            <!-- Section 4 -->
            <div class="mb-16 hover-scale">
                <div class="flex items-center mb-6">
                    <div class="bg-blue-100 rounded-full w-12 h-12 flex items-center justify-center mr-4">
                        <span class="text-blue-600 text-xl font-bold">4</span>
                    </div>
                    <h2 class="text-2xl md:text-3xl font-bold text-slate-800">修改SQL语句</h2>
                </div>
                <div class="pl-16">
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        分页插件的核心操作是修改SQL语句，加入分页参数。不同的数据库有不同的分页语法，因此分页插件需要根据数据库的类型来生成合适的SQL语句。
                    </p>
                    
                    <div class="code-block shadow-soft mb-6">
                        <pre><code class="language-java">private String buildPageSql(String originalSql, PageBounds pageBounds) {
    // 生成 MySQL 分页 SQL
    StringBuilder pageSql = new StringBuilder(originalSql);
    pageSql.append(" LIMIT ").append(pageBounds.getOffset()).append(", ").append(pageBounds.getLimit());
    return pageSql.toString();
}</code></pre>
                    </div>
                    
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        对于其他数据库（如Oracle、PostgreSQL等），分页的SQL语法会有所不同。因此，分页插件需要根据数据库方言进行判断，并生成不同的SQL。
                    </p>
                    
                    <div class="code-block shadow-soft mb-6">
                        <pre><code class="language-java">private String buildPageSql(String originalSql, PageBounds pageBounds) {
    String dbDialect = getDatabaseDialect();
    if ("mysql".equals(dbDialect)) {
        return buildMysqlPageSql(originalSql, pageBounds);
    } else if ("oracle".equals(dbDialect)) {
        return buildOraclePageSql(originalSql, pageBounds);
    } else {
        throw new UnsupportedOperationException("不支持的数据库类型");
    }
}

private String buildMysqlPageSql(String originalSql, PageBounds pageBounds) {
    // 生成 MySQL 分页 SQL
    return originalSql + " LIMIT " + pageBounds.getOffset() + ", " + pageBounds.getLimit();
}

private String buildOraclePageSql(String originalSql, PageBounds pageBounds) {
    // 生成 Oracle 分页 SQL
    return "SELECT * FROM (SELECT A.*, ROWNUM RN FROM (" + originalSql + ") A WHERE ROWNUM <= "
            + (pageBounds.getOffset() + pageBounds.getLimit()) + ") WHERE RN > " + pageBounds.getOffset();
}</code></pre>
                    </div>
                </div>
            </div>

            <!-- Section 5 -->
            <div class="mb-16 hover-scale">
                <div class="flex items-center mb-6">
                    <div class="bg-blue-100 rounded-full w-12 h-12 flex items-center justify-center mr-4">
                        <span class="text-blue-600 text-xl font-bold">5</span>
                    </div>
                    <h2 class="text-2xl md:text-3xl font-bold text-slate-800">执行SQL的修改</h2>
                </div>
                <div class="pl-16">
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        在SQL语句被修改之后，分页插件将修改后的SQL设置回<code class="bg-blue-50 text-blue-600 px-1 rounded">BoundSql</code>对象，确保MyBatis执行的是分页后的SQL。
                    </p>
                    
                    <div class="code-block shadow-soft mb-6">
                        <pre><code class="language-java">private void setPageSqlToBoundSql(BoundSql boundSql, String pageSql) {
    try {
        // 获取 BoundSql 中的 sql 字段并修改
        Field sqlField = BoundSql.class.getDeclaredField("sql");
        sqlField.setAccessible(true);
        sqlField.set(boundSql, pageSql);  // 替换原 SQL 为分页后的 SQL
    } catch (NoSuchFieldException | IllegalAccessException e) {
        e.printStackTrace();
    }
}</code></pre>
                    </div>
                    
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        通过这种方式，分页插件在SQL执行之前修改了SQL语句，加入了分页相关的语法，确保查询只返回分页数据。
                    </p>
                </div>
            </div>

            <!-- Section 6 -->
            <div class="mb-16 hover-scale">
                <div class="flex items-center mb-6">
                    <div class="bg-blue-100 rounded-full w-12 h-12 flex items-center justify-center mr-4">
                        <span class="text-blue-600 text-xl font-bold">6</span>
                    </div>
                    <h2 class="text-2xl md:text-3xl font-bold text-slate-800">插件的性能优化</h2>
                </div>
                <div class="pl-16">
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        分页插件的设计和实现要考虑性能，特别是在大数据量查询时。以下是分页插件优化的一些常见方法：
                    </p>
                    
                    <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
                        <div class="bg-white p-4 rounded-lg shadow-soft">
                            <div class="flex items-center mb-2">
                                <div class="bg-blue-100 text-blue-600 rounded-full w-6 h-6 flex items-center justify-center mr-2">
                                    <i class="fas fa-bolt text-xs"></i>
                                </div>
                                <h4 class="font-bold text-sm text-slate-800">避免不必要修改</h4>
                            </div>
                            <p class="text-slate-700 text-xs">
                                在没有分页需求时，不要修改SQL
                            </p>
                        </div>
                        <div class="bg-white p-4 rounded-lg shadow-soft">
                            <div class="flex items-center mb-2">
                                <div class="bg-blue-100 text-blue-600 rounded-full w-6 h-6 flex items-center justify-center mr-2">
                                    <i class="fas fa-boxes text-xs"></i>
                                </div>
                                <h4 class="font-bold text-sm text-slate-800">批量查询优化</h4>
                            </div>
                            <p class="text-slate-700 text-xs">
                                通过分批查询来减少一次性查询的压力
                            </p>
                        </div>
                        <div class="bg-white p-4 rounded-lg shadow-soft">
                            <div class="flex items-center mb-2">
                                <div class="bg-blue-100 text-blue-600 rounded-full w-6 h-6 flex items-center justify-center mr-2">
                                    <i class="fas fa-database text-xs"></i>
                                </div>
                                <h4 class="font-bold text-sm text-slate-800">缓存机制</h4>
                            </div>
                            <p class="text-slate-700 text-xs">
                                对频繁查询的分页数据使用缓存
                            </p>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Section 7 -->
            <div class="mb-16 hover-scale">
                <div class="flex items-center mb-6">
                    <div class="bg-blue-100 rounded-full w-12 h-12 flex items-center justify-center mr-4">
                        <span class="text-blue-600 text-xl font-bold">7</span>
                    </div>
                    <h2 class="text-2xl md:text-3xl font-bold text-slate-800">多种数据库方言的支持</h2>
                </div>
                <div class="pl-16">
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        分页插件通常需要支持多种数据库的分页语法，因此需要根据数据库方言生成对应的SQL。常见的数据库分页语法如下：
                    </p>
                    
                    <div class="overflow-x-auto mb-6">
                        <table class="min-w-full bg-white rounded-lg overflow-hidden shadow-soft">
                            <thead class="bg-blue-50">
                                <tr>
                                    <th class="px-4 py-3 text-left text-xs font-medium text-blue-600 uppercase tracking-wider">数据库</th>
                                    <th class="px-4 py-3 text-left text-xs font-medium text-blue-600 uppercase tracking-wider">分页语法</th>
                                </tr>
                            </thead>
                            <tbody class="divide-y divide-gray-200">
                                <tr>
                                    <td class="px-4 py-3 whitespace-nowrap text-sm text-slate-700">MySQL</td>
                                    <td class="px-4 py-3 whitespace-nowrap text-sm font-mono text-blue-600">LIMIT offset, limit</td>
                                </tr>
                                <tr>
                                    <td class="px-4 py-3 whitespace-nowrap text-sm text-slate-700">Oracle</td>
                                    <td class="px-4 py-3 whitespace-nowrap text-sm font-mono text-blue-600">SELECT * FROM (SELECT ... WHERE ROWNUM <= n) WHERE ROWNUM > m</td>
                                </tr>
                                <tr>
                                    <td class="px-4 py-3 whitespace-nowrap text-sm text-slate-700">PostgreSQL</td>
                                    <td class="px-4 py-3 whitespace-nowrap text-sm font-mono text-blue-600">LIMIT limit OFFSET offset</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                    
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        分页插件的设计需要兼容这些不同的数据库方言，确保其可以在各种数据库环境下正常工作。
                    </p>
                </div>
            </div>

            <!-- Section 8 -->
            <div class="mb-16 hover-scale">
                <div class="flex items-center mb-6">
                    <div class="bg-blue-100 rounded-full w-12 h-12 flex items-center justify-center mr-4">
                        <span class="text-blue-600 text-xl font-bold">8</span>
                    </div>
                    <h2 class="text-2xl md:text-3xl font-bold text-slate-800">分页插件的集成与配置</h2>
                </div>
                <div class="pl-16">
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        分页插件可以通过MyBatis的插件机制集成到整个框架中。通过在<code class="bg-blue-50 text-blue-600 px-1 rounded">mybatis-config.xml</code>中配置分页插件，可以使得插件在所有查询操作中生效。
                    </p>
                    
                    <div class="code-block shadow-soft mb-6">
                        <pre><code class="language-xml">&lt;plugins&gt;
    &lt;plugin interceptor="com.example.PageHelper"&gt;
        &lt;property name="dialect" value="mysql"/&gt;  &lt;!-- 设置数据库方言 --&gt;
    &lt;/plugin&gt;
&lt;/plugins&gt;</code></pre>
                    </div>
                    
                    <p class="text-slate-700 mb-4 leading-relaxed">
                        通过上述配置，MyBatis会自动加载并应用分页插件。分页插件会在SQL执行过程中动态修改查询语句，加入分页功能。
                    </p>
                </div>
            </div>

            <!-- Visualization Section -->
            <div id="visualization" class="mb-16 bg-white p-8 rounded-xl shadow-soft hover:shadow-hover transition-shadow duration-200">
                <div class="flex items-center mb-6">
                    <div class="bg-blue-100 rounded-full w-12 h-12 flex items-center justify-center mr-4">
                        <i class="fas fa-project-diagram text-blue-600 text-xl"></i>
                    </div>
                    <h2 class="text-2xl md:text-3xl font-bold text-slate-800">分页插件工作原理可视化</h2>
                </div>
                
                <div class="mermaid">
                    sequenceDiagram
                        participant Client
                        participant MyBatisFramework
                        participant PagePlugin
                        participant StatementHandler
                        participant Database

                        Client->>MyBatisFramework: 执行查询请求(带分页参数)
                        MyBatisFramework->>PagePlugin: 调用拦截器
                        PagePlugin->>StatementHandler: 拦截prepare()方法
                        StatementHandler->>PagePlugin: 返回原始SQL
                        PagePlugin->>PagePlugin: 修改SQL(添加分页语法)
                        PagePlugin->>StatementHandler: 返回修改后的SQL
                        StatementHandler->>Database: 执行分页SQL
                        Database-->>StatementHandler: 返回分页结果
                        StatementHandler-->>MyBatisFramework: 返回结果
                        MyBatisFramework-->>Client: 返回分页数据
                </div>
            </div>
        </div>
    </section>

    <!-- Footer -->
    <footer class="bg-slate-900 text-white py-12 px-4">
        <div class="container mx-auto max-w-4xl">
            <div class="flex flex-col items-center">
                <div class="mb-4">
                    <h3 class="text-xl font-bold">技术小馆</h3>
                </div>
                <div class="mb-6">
                    <a href="http://www.yuque.com/jtostring" class="text-blue-400 hover:text-blue-300 transition-colors duration-200">
                        <i class="fas fa-globe mr-2"></i>http://www.yuque.com/jtostring
                    </a>
                </div>
                <div class="text-sm text-slate-400">
                    &copy; 2023 技术小馆. 保留所有权利.
                </div>
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            },
            sequence: {
                diagramMarginX: 50,
                diagramMarginY: 10,
                boxMargin: 10,
                width: 200,
                height: 100
            }
        });
        
        // 平滑滚动
        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                document.querySelector(this.getAttribute('href')).scrollIntoView({
                    behavior: 'smooth'
                });
            });
        });
    </script>
</body>
</html>
```